package com.jinjiafeng.framelibrary.skin;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.text.TextUtils;
import android.util.ArrayMap;

import com.jinjiafeng.framelibrary.skin.attr.SkinView;
import com.jinjiafeng.framelibrary.skin.callback.ISkinChangeListener;
import com.jinjiafeng.framelibrary.skin.config.SkinConfig;
import com.jinjiafeng.framelibrary.skin.config.SkinPreUtils;

import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Created by jinjiafeng.
 * date:on 18-5-9
 */

public class SkinManager {

    @SuppressLint("StaticFieldLeak")
    private static SkinManager mInstance;

    static {
        mInstance = new SkinManager();
    }

    private Context mContext;
    private Map<ISkinChangeListener, List<SkinView>> mSkinViewsMap = new ArrayMap<>();
    private SkinResource mSkinResource;

    public static SkinManager getInstance() {
        return mInstance;
    }

    public void init(Context context) {
        mContext = context.getApplicationContext();
        String skinPath = getSkinPath();
        if (TextUtils.isEmpty(skinPath)) {
            return;
        }
        File file = new File(skinPath);
        if (!file.exists()) {
            SkinPreUtils.getInstance(mContext).clearSkinInfo();
            return;
        }

        if (checkPackageName(skinPath)) {
            SkinPreUtils.getInstance(mContext).clearSkinInfo();
            return;
        }

        mSkinResource = new SkinResource(mContext, skinPath);

    }

    private String getSkinPath() {
        return SkinPreUtils.getInstance(mContext).getSkinPath();
    }

    /**
     * 检查当前皮肤路径是否存在包名
     *
     * @param skinPath 加载的皮肤路径
     * @return 检查包名是否存在的结构
     */
    private boolean checkPackageName(String skinPath) {
        String packageName = mContext.getPackageManager().getPackageArchiveInfo(skinPath, PackageManager.GET_ACTIVITIES).packageName;
        return !TextUtils.isEmpty(packageName);
    }

    public int loadSkin(String skinPath) {
        if (skinPath.equals(getSkinPath())) {
            return SkinConfig.SKIN_CHANGE_NOTHING;
        }

        File file = new File(skinPath);
        if (!file.exists()) {
            return SkinConfig.SKIN_FILE_NOEXSIST;
        }

        if (checkPackageName(skinPath)) {
            return SkinConfig.SKIN_FILE_ERROR;
        }


        //获取SkinResource
        mSkinResource = new SkinResource(mContext, skinPath);
        //遍历需要换肤的view，更换皮肤
        changeSkin();

        saveSkinStatus(skinPath);

        return SkinConfig.SKIN_CHANGE_SUCCESS;
    }

    private void changeSkin() {
        Set<Map.Entry<ISkinChangeListener, List<SkinView>>> entries = mSkinViewsMap.entrySet();
        for (Map.Entry<ISkinChangeListener, List<SkinView>> entry : entries) {
            List<SkinView> skinViews = entry.getValue();
            for (SkinView skinView : skinViews) {
                skinView.skin();
            }
            entry.getKey().changeSkin(mSkinResource);
        }
    }

    private void saveSkinStatus(String skinPath) {
        SkinPreUtils.getInstance(mContext).saveSkinPath(skinPath);
    }

    /**
     * 皮肤恢复默认
     *
     * @return 换肤的结果
     */
    public int restoreDefault() {
        String skinPath = getSkinPath();
        //没有换肤，直接返回
        if (TextUtils.isEmpty(skinPath)) {
            return SkinConfig.SKIN_CHANGE_NOTHING;
        }
        //获取系统当前资源路径
        String resourcePath = mContext.getPackageResourcePath();
        //获取SkinResource
        mSkinResource = new SkinResource(mContext, resourcePath);
        changeSkin();
        //清楚皮肤配置信息
        SkinPreUtils.getInstance(mContext).clearSkinInfo();
        return SkinConfig.SKIN_CHANGE_SUCCESS;
    }

    public void register(ISkinChangeListener listener, List<SkinView> skinViews) {
        mSkinViewsMap.put(listener, skinViews);
    }

    public List<SkinView> getSkinView(ISkinChangeListener listener) {
        return mSkinViewsMap.get(listener);
    }

    public SkinResource getSkinResource() {
        return mSkinResource;
    }


    /**
     * 防止内存泄露
     */
    public void unregister(ISkinChangeListener skinChangeListener) {
        mSkinViewsMap.remove(skinChangeListener);
    }
}
